#ifndef CHARACTERCLASS_H
#define CHARACTERCLASS_H


#include "dtwenty_global.h"
#include "dtwentyitem.h"
#include "dtwentyitemcontainer.h"
#include "skill.h"


class DTWENTYSHARED_EXPORT CharacterClass : public DTwentyItem
{
    Q_OBJECT

public:

    enum HitDie
    {
        D4 = 4,
        D6 = 6,
        D8 = 8,
        D10 = 10,
        D12 = 12
    };

    enum SkillPoints
    {
        Untrained = 2,
        Educated = 4,
        Expert = 6,
        Master = 8
    };

    enum BaseBonus
    {
        Poor = 0,
        Ordinary = 1,
        Excellent = 2
    };

    enum SaveBonus
    {
        Normal = 0,
        Good = 1
    };

private:


    class Data : public QSharedData
    {
    public:

        Data()
        {
            hitDie = CharacterClass::D4;
            skillPoints = CharacterClass::Untrained;
            baseAttack = CharacterClass::Poor;
            fortSave = CharacterClass::Normal;
            refSave = CharacterClass::Normal;
            willSave = CharacterClass::Normal;
        }

        Data(const Data& other) : QSharedData(other)
        {
            hitDie = other.hitDie;
            skillPoints = other.skillPoints;
            baseAttack = other.baseAttack;
            fortSave = other.fortSave;
            refSave = other.refSave;
            willSave = other.willSave;
        }

        CharacterClass::HitDie hitDie;
        CharacterClass::SkillPoints skillPoints;
        CharacterClass::BaseBonus baseAttack;
        CharacterClass::SaveBonus fortSave;
        CharacterClass::SaveBonus refSave;
        CharacterClass::SaveBonus willSave;
    };

    Q_ENUMS(HitDie SkillPoints BaseBonus SaveBonus)

    Q_PROPERTY(HitDie hitDie READ hitDie WRITE setHitDie)
    Q_PROPERTY(SkillPoints skillPoints READ skillPoints WRITE setSkillPoints)
    Q_PROPERTY(BaseBonus baseAttack READ baseAttack WRITE setBaseAttack)
    Q_PROPERTY(SaveBonus fortSave READ fortSave WRITE setFortSave)
    Q_PROPERTY(SaveBonus refSave READ refSave WRITE setRefSave)
    Q_PROPERTY(SaveBonus willSave READ willSave WRITE setWillSave)



public:

    Q_INVOKABLE CharacterClass(QObject *parent = 0);
    CharacterClass(const CharacterClass& other);

    virtual int type() const;

    HitDie hitDie() const;
    void setHitDie(HitDie hitDie);

    SkillPoints skillPoints() const;
    void setSkillPoints(SkillPoints skillPoints);

    BaseBonus baseAttack() const
    {
        return d->baseAttack;
    }

    SaveBonus fortSave() const
    {
        return d->fortSave;
    }
    SaveBonus refSave() const
    {
        return d->refSave;
    }

    SaveBonus willSave() const
    {
        return d->willSave;
    }

    static int calcBaseBonus(int level, int category);
    static int calcSaveBonus(int level, int category);


public slots:
    void setBaseAttack(BaseBonus arg)
    {
        d->baseAttack = arg;
    }

    void setFortSave(SaveBonus arg)
    {
        d->fortSave = arg;
    }

    void setRefSave(SaveBonus arg)
    {
        d->refSave = arg;
    }

    void setWillSave(SaveBonus arg)
    {
        d->willSave = arg;
    }


protected slots:

    virtual void onInitChildren();


private:

    QSharedDataPointer<Data> d;


};
Q_DECLARE_METATYPE(CharacterClass)


class DTWENTYSHARED_EXPORT CharacterClasses : public DTwentyItemContainer
{
    Q_OBJECT

    Q_PROPERTY(QString hitDieTitle READ hitDieTitle)
    Q_PROPERTY(QString skillPointsTitle READ skillPointsTitle)
    Q_PROPERTY(QString baseAttackTitle READ baseAttackTitle)
    Q_PROPERTY(QString fortSaveTitle READ fortSaveTitle)
    Q_PROPERTY(QString refSaveTitle READ refSaveTitle)
    Q_PROPERTY(QString willSaveTitle READ willSaveTitle)


public:

    Q_INVOKABLE CharacterClasses(QObject *parent = 0) :
        DTwentyItemContainer(parent)
    {
        registerChildType<CharacterClass>();
    }

    CharacterClasses(const CharacterClasses& other) :
        DTwentyItemContainer(other)
    {
    }

    virtual int type() const
    {
        return qMetaTypeId<CharacterClasses*>();
    }

    QString hitDieTitle() const
    {
        return tr("Hit Die");
    }
    QString skillPointsTitle() const
    {
        return tr("Skill Points");
    }
    QString baseAttackTitle() const
    {
        return tr("Base Attack");
    }
    QString fortSaveTitle() const
    {
        return tr("Fort Save");
    }
    QString refSaveTitle() const
    {
        return tr("Ref Save");
    }
    QString willSaveTitle() const
    {
        return tr("Will Save");
    }
};
Q_DECLARE_METATYPE(CharacterClasses)

#endif // CHARACTERCLASS_H
